package io.github.xyzboom.cj.data

import DebugSession

class DebugData(val session: DebugSession) {
    // key: seqId, value: expression to be evaluated
    val evalSeqIds: HashMap<Int, String> = HashMap()

    // key: seqId, value: varId
    val varSeqIds = HashMap<Int, Int>()

    // key: var id, value: expr eval str -- parent id
    // note that VarId is used for variables that has id 0 whose children is empty.
    val lookupChildrenVar = HashMap<Int, Pair<String, Int>>()

    // key: variable id, value: children ids
    val variables: HashMap<VarId, DebugVariable> = HashMap()

    // key: expression to be evaluated, value: expression
    val exprMap = HashMap<String, DebugExpression>()

    // key: expression id, value: expression
    // note exprIdMap shares instance with exprMap
    val exprIdMap = HashMap<Int, DebugExpression>()

    // key: seqId, value: expression id
    val evalCheckPosSeqIds = HashMap<Int, Int>()

    val checkBeginLineSeqIds = HashSet<Int>()
    val checkBeginColumnSeqIds = HashSet<Int>()
    val checkEndLineSeqIds = HashSet<Int>()
    val checkEndColumnSeqIds = HashSet<Int>()

    fun setExprPosition(expr: DebugExpression, seqId: Int, pos: Int) {
        if (checkBeginLineSeqIds.remove(seqId)) {
            expr.beginLine = pos
        } else if (checkBeginColumnSeqIds.remove(seqId)) {
            expr.beginColumn = pos
        } else if (checkEndLineSeqIds.remove(seqId)) {
            expr.endLine = pos
        } else if (checkEndColumnSeqIds.remove(seqId)) {
            expr.endColumn = pos
        }
    }

    fun buildRawCjNode(varId: VarId, parent: RawCjNode? = null): RawCjNode? {
        if (varId.isNull) {
            return null
        }
        val variable = variables[varId] ?: return null
        val node = RawCjNode(variable, parent)
        for (childId in variable.childrenIds) {
            val child = buildRawCjNode(childId, node) ?: continue
            node.children.add(child)
        }
        return node
    }
}